// Written by Dale J Williams.
// Licensed under MPL 1.1 unless otherwise specified. 
// http://www.mozilla.org/MPL/MPL-1.1.html

package engineDJW.screens {
	
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.Stage;
	import flash.events.Event;
	
	/**
	 * ...
	 * @author Dale J Williams
	 */
	public class ScreenManager {
		
		private var _parent		:DisplayObjectContainer;
		private var _stage		:Stage;
		private var _screens	:Object;
		private var _screen		:GameScreen;
		private var _prevScreen	:GameScreen;
		private var _switching	:Boolean;
		
		public function ScreenManager($parent:DisplayObjectContainer) {
			_parent = $parent;
			_stage = $parent.stage;
			_screens = {};
		}
		
		public function addScreen($screen:GameScreen, $switchTo:Boolean = false):void {
			if (_screens[$screen.name]) throw new Error("Screen of specified name already exists.");
			_screens[$screen.name] = $screen;
			if ($switchTo) switchTo($screen);
		}
		
		public function getScreen($name:String):GameScreen {
			return _screens[$name] as GameScreen;
		}
		
		public function switchTo($screenOrScreenName:Object):void {
			if ($screenOrScreenName is String)
				if (_screens.hasOwnProperty(String($screenOrScreenName)))
					switchToScreen(_screens[$screenOrScreenName]);
				else throw new Error("ScreenManager contains no screen by that name.");
			else if ($screenOrScreenName is GameScreen)
				switchToScreen(GameScreen($screenOrScreenName));
			else throw new Error("GameScreen is not valid.");
		}
		
		private function switchToScreen($screen:GameScreen):void {
			if ($screen == _screen) return;
			_prevScreen = _screen;
			_screen = $screen;
			_screen.visible = _screen.mouseEnabled = _screen.mouseChildren = true;
			if (_prevScreen) {
				_prevScreen.addEventListener(GameScreen.REMOVED, completeSwitch);
				_prevScreen.animOut();
			} else addNext();
		}
		
		private function completeSwitch(e:Event):void {
			_prevScreen.removeEventListener(GameScreen.REMOVED, completeSwitch);
			_prevScreen.visible = _prevScreen.mouseEnabled = _prevScreen.mouseChildren = false;
			remove(_prevScreen);
			_prevScreen = null;
			addNext();
		}
		
		private function addNext():void {			
			add(_screen);
			_screen.animIn();
			_screen.focusRect = false;
			_screen.parent.setChildIndex(_screen, _screen.parent.numChildren - 1);
			_stage.focus = _screen;
		}
				
		public function add($screen:GameScreen):void {
			$screen.manager = this;
			parent.addChild($screen);
		}
		
		public function remove($screen:GameScreen):void {
			$screen.parent.removeChild($screen);
			$screen.manager = null;
		}
		
		public function get parent():DisplayObjectContainer { return _parent; }
		
		public function get screen():GameScreen { return _screen; }
		
	}

}